﻿Module Configuration
    ''' <summary>
    ''' Generic Structure to handle the entire Application Configuration
    ''' </summary>
    ''' <remarks></remarks>
    Public Structure ApplicationConfiguration
        Public InputFilename As String
        Public PrintHelpOnly As Boolean
        Public Verbose As Boolean
        Public UseExternalApi As Boolean ' When true, this executable will not unpack ArpsEngine.dll and HGLEngine.dll from itself
        Public PackOnly As Boolean ' When true, this executable will only Pack its required Dlls inside itself and exit
        Public Standalone As Boolean ' Specified if this app is packed with all user dlls required for operation
        Public Unattended As Boolean ' When true, Application will not request a key press to end
        Public PackagePassword As String ' Specifies the password used to decrypt Encrypted packages (if supported). Protocol Dependant
    End Structure

    Public CurrentConfiguration As ApplicationConfiguration
    Public DefaultConfiguration As ApplicationConfiguration

    ''' <summary>
    ''' Initializes the Application with the Default configuration
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub InitializeDefaultConfiguration()
        With DefaultConfiguration
            .InputFilename = Nothing
            .PrintHelpOnly = False
            .Verbose = False
            .UseExternalApi = False
            .PackOnly = False
            .Standalone = False
            .Unattended = False
            .PackagePassword = ""
        End With

        CurrentConfiguration = DefaultConfiguration

        Try
            ' Try to increment the Console buffer and window height (if its 80 or less only)
            If Console.BufferWidth <= 80 Then
                Console.BufferWidth = 100
            End If
            If Console.WindowWidth <= 80 Then
                Console.WindowWidth = 100
            End If
        Catch
            ' Ignore
        End Try

        Dim appPrefix As String = "?"
        Try
            ' Try to get if this executable is a Packed Standalone
            Dim fs As New IO.FileStream(System.Reflection.Assembly.GetExecutingAssembly().Location, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
            fs.Position = fs.Length - 6 ' - 6 bytes of PACKED string
            Dim buffer(5) As Byte
            fs.Read(buffer, 0, 6)
            fs.Close()
            fs.Dispose()
            fs = Nothing

            Dim signature As String = System.Text.Encoding.ASCII.GetString(buffer)
            If signature = "PACKED" Then
                appPrefix = "Standalone "
                CurrentConfiguration.Standalone = True
            Else
                appPrefix = ""
            End If
        Catch ex As Exception
            ' Ignore
        End Try

        Try
            ' Try to set the Console Title
            Dim myProcess As Process
            myProcess = Process.GetCurrentProcess
            Console.Title = appPrefix & "APC - PID:" & myProcess.Id
            myProcess.Dispose()
        Catch
            ' Ignore
        End Try
    End Sub

    ''' <summary>
    ''' Process every command line specified at launch time
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub ProcessCommandLineParameters()
        If My.Application.CommandLineArgs.Count = 0 Then Exit Sub

        Dim i As Integer
        For i = 0 To My.Application.CommandLineArgs.Count - 1
            Dim parameter As String
            parameter = My.Application.CommandLineArgs(i)
            parameter = Trim(parameter)
            If parameter Like "/*=*" Then
                ' Parameter is a Modifier
                Dim command As String
                Dim value As String
                Dim tmpSplitted() As String
                tmpSplitted = Split(parameter, "=")
                If Not tmpSplitted.Length = 2 Then
                    AddLog(" Invalid parameter <" & parameter & "> specified.")
                    GoTo NextLoop
                End If
                command = tmpSplitted(0)
                value = tmpSplitted(1)
                command = Right(command, command.Length - 1) ' Remove the head '/'
                command = LCase(command)
                command = Trim(command)
                value = Trim(value)
                If command = "" Then
                    AddLog(" Invalid parameter <" & parameter & "> specified.")
                    GoTo NextLoop
                End If
                If value = "" Then
                    AddLog(" Invalid parameter <" & parameter & "> specified.")
                    GoTo NextLoop
                End If
                CheckModifierParameter(command, value)
            ElseIf parameter Like "/*" Then
                ' Parameter is a Switch
                Dim switch As String
                switch = parameter
                switch = Trim(switch)
                switch = Right(switch, switch.Length - 1) ' Remove the head '/'
                CheckSwitchParameter(switch)
            Else
                ' Parameter is a filename
                Dim value As String
                value = parameter
                CheckModifierParameter("file", value)
            End If
NextLoop:
        Next
    End Sub
    ''' <summary>
    ''' Checks and applies a Switch parameter (/something)
    ''' </summary>
    ''' <param name="switch">Switch to be applied</param>
    ''' <remarks></remarks>
    Public Sub CheckSwitchParameter(ByVal switch As String)
        Select Case switch
            Case "verbose", "v"
                CurrentConfiguration.Verbose = True
            Case "help", "h", "?"
                CurrentConfiguration.PrintHelpOnly = True
            Case "externalapi", "xpi"
                CurrentConfiguration.UseExternalApi = True
            Case "packdlls"
                CurrentConfiguration.PackOnly = True
            Case "unattended"
                CurrentConfiguration.Unattended = True
            Case Else
                AddLog("Unrecognized switch <" & switch & ">")
                Exit Sub
        End Select
    End Sub
    ''' <summary>
    ''' Checks and applies a Modifier parameter (/something=value)
    ''' </summary>
    ''' <param name="command">Command that represents a value that will be changed</param>
    ''' <param name="parameter">The new value of command</param>
    ''' <remarks></remarks>
    Public Sub CheckModifierParameter(ByVal command As String, ByVal parameter As String)
        Select Case command
            Case "file", "in", "i"
                ' Adds a source file to the compilation queue
                If Configuration.CurrentConfiguration.InputFilename = "" Then
                    Configuration.CurrentConfiguration.InputFilename = parameter
                Else
                    AddLog("WARNING: Duplicated input file. First one will be used.")
                End If
            Case "root", "r"
                ' Specifies the working path of the application
                Dim di As New IO.DirectoryInfo(parameter)
                If di.Exists = False Then
                    AddLog("Cant set root directory to <" & parameter & ">.")
                    AddLog("Missing directory.")
                Else
                    IO.Directory.SetCurrentDirectory(di.FullName)
                    AddLog("New root directory successfully set.")
                    AddLog(" :" & di.FullName)
                End If
            Case "password", "psw"
                ' Specified the password used to decrypt Encrypted Packages when supported by Protocol
                Configuration.CurrentConfiguration.PackagePassword = parameter
            Case Else
                AddLog("Unrecognized modifier <" & command & ">")
                Exit Sub
        End Select
    End Sub
End Module


